package com.andnnl.reflect;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.sql.rowset.CachedRowSet;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 通过反射装配到Bean
 * Created by chenss on 2022/4/25.
 */
public class ReflectUtil {
    private static final Logger logger = LoggerFactory.getLogger(ReflectUtil.class);

    @SuppressWarnings({"rawtypes", "unchecked"})
    public static <T> T fillData(Class clazz, CachedRowSet crs) {
        try {
            T t = (T) clazz.newInstance();
//            Field[] fields = clazz.getDeclaredFields();
            Field[] fields = ReflectionUtils.getDeclaredFields(clazz);//缓存起来
            for (int i = 0; i < fields.length; i++) {
                fields[i].setAccessible(true);
                NoReflection nr = fields[i].getAnnotation(NoReflection.class);
                if (nr != null) continue;
                try {
                    String fieldsName = fields[i].getName();
                    Class<?> fieldsType = fields[i].getType();
                    if (fieldsType.equals(Date.class)) {
                        //Date
                        fields[i].set(t, crs.getDate(fieldsName));
                    } else if (fieldsType.equals(Double.class)) {
                        //Double
                        fields[i].set(t, crs.getDouble(fieldsName));
                    } else if (fieldsType.equals(Integer.class)) {
                        //Integer
                        fields[i].set(t, crs.getInt(fieldsName));
                    } else if (fieldsType.equals(Short.class)) {
                        //Shout
                        fields[i].set(t, crs.getShort(fieldsName));
                    } else if (fieldsType.equals(String.class)) {
                        //String
                        String str = crs.getString(fieldsName);
//                        if("null".equals(str) || str==null){
//                            str = "";
//                        }
                        fields[i].set(t, str);
                    } else if (fieldsType.equals(Float.class)) {
                        //Float
                        fields[i].set(t, crs.getFloat(fieldsName));
                    } else if (fieldsType.equals(Long.class)) {
                        //Long
                        fields[i].set(t, crs.getLong(fieldsName));
                    } else if (fieldsType.equals(Byte.class)) {
                        //Byte
                        fields[i].set(t, crs.getByte(fieldsName));
                    } else if (fieldsType.equals(BigDecimal.class)) {
                        //BigDecimal
                        fields[i].set(t, crs.getBigDecimal(fieldsName));
                    } else if (fieldsType.equals(byte[].class)) {
                        //byte[]
                        fields[i].set(t, crs.getBytes(fieldsName));
                    } else if (fieldsType.equals(Boolean.class)) {
                        //Boolean
                        fields[i].set(t, crs.getBoolean(fieldsName));
                    } else if (fieldsType.equals(BigInteger.class)) {
                        //BigInteger
                        fields[i].set(t, crs.getInt(fieldsName));
                    } else {
                        fields[i].set(t, crs.getObject(fieldsName));
                    }
//                    fields[i].set(t, crs.getObject(fields[i].getName()));
                } catch (Exception e) {
//                    logger.info("==反射字段列名无效：" + fields[i].getName());
//					logger.error("catch Exception",e);
                }
            }
            return t;
        } catch (Exception e) {
            logger.error("catch Exception", e);
            return null;
        }

    }

    @SuppressWarnings({"rawtypes", "unchecked"})
    public static <T> T fillData(Class clazz, ResultSet crs) {
        try {
            T t = (T) clazz.newInstance();
            Field[] fields = ReflectionUtils.getDeclaredFields(clazz);//缓存起来
            for (int i = 0; i < fields.length; i++) {
                fields[i].setAccessible(true);
                NoReflection nr = fields[i].getAnnotation(NoReflection.class);
                if (nr != null) continue;
                try {
                    String fieldsName = fields[i].getName();
                    Class<?> fieldsType = fields[i].getType();
                    if (fieldsType.equals(Date.class)) {
                        //Date
                        fields[i].set(t, crs.getDate(fieldsName));
                    } else if (fieldsType.equals(Double.class)) {
                        //Double
                        fields[i].set(t, crs.getDouble(fieldsName));
                    } else if (fieldsType.equals(Integer.class)) {
                        //Integer
                        fields[i].set(t, crs.getInt(fieldsName));
                    } else if (fieldsType.equals(Short.class)) {
                        //Shout
                        fields[i].set(t, crs.getShort(fieldsName));
                    } else if (fieldsType.equals(String.class)) {
                        //String
                        String str = crs.getString(fieldsName);
//                        if("null".equals(str) || str==null){
//                            str = "";
//                        }
                        fields[i].set(t, str);
                    } else if (fieldsType.equals(Float.class)) {
                        //Float
                        fields[i].set(t, crs.getFloat(fieldsName));
                    } else if (fieldsType.equals(Long.class)) {
                        //Long
                        fields[i].set(t, crs.getLong(fieldsName));
                    } else if (fieldsType.equals(Byte.class)) {
                        //Byte
                        fields[i].set(t, crs.getByte(fieldsName));
                    } else if (fieldsType.equals(BigDecimal.class)) {
                        //BigDecimal
                        fields[i].set(t, crs.getBigDecimal(fieldsName));
                    } else if (fieldsType.equals(byte[].class)) {
                        //byte[]
                        fields[i].set(t, crs.getBytes(fieldsName));
                    } else if (fieldsType.equals(Boolean.class)) {
                        //Boolean
                        fields[i].set(t, crs.getBoolean(fieldsName));
                    } else if (fieldsType.equals(BigInteger.class)) {
                        //BigInteger
                        fields[i].set(t, crs.getInt(fieldsName));
                    } else {
                        fields[i].set(t, crs.getObject(fieldsName));
                    }
//                    fields[i].set(t, crs.getObject(fields[i].getName()));
                } catch (Exception e) {
//                    logger.info("==反射字段列名无效：" + fields[i].getName());
//					logger.error("catch Exception",e);
                }
            }
            return t;
        } catch (Exception e) {
            logger.error("catch Exception", e);
            return null;
        }

    }

    /**
     * 返回所有的Fields包括父类的
     *
     * @param clazz
     * @return
     */
    public static List<Field> getAllFields(Class<?> clazz) {
        List<Field> result = new ArrayList<>();
        if (clazz == null) {
            return result;
        }
        for (Field f : clazz.getDeclaredFields()) {
            result.add(f);
        }
        //内部类
        for (Class aClass : clazz.getDeclaredClasses()) {
            result.addAll(getAllFields(aClass));
        }
        result.addAll(getAllFields(clazz.getSuperclass()));


        return result;
    }
}
